#include "StdAfx.h"
#include "TvLayoutManager.h"
#include "MonitorClient.h"
#include "MultiDisplayDlg.h"
#include "MonitorMessage.h"
#include "MonitorPlatform.h"
//#include "DBManager.h"
//#include "ApplicationData.h"

CTvLayoutManager::CTvLayoutManager(void)
: m_pMultiDisplayDlg(NULL)
, m_ActiveLayoutIter(EndOfLayoutList())
, m_bTouring(FALSE)
, m_bEnableSelChange(FALSE)
{
	m_TourTimer.SetTimerProc(LayoutTourTimerProc, this);
}

CTvLayoutManager::~CTvLayoutManager(void)
{
	CTvWallLayoutPtrList::iterator it = m_Layoutlist.begin();
	for(; it != m_Layoutlist.end(); ++it)
	{
		delete *it;
	}
}

BOOL CTvLayoutManager::Initialize(CMultiDisplayDlg* pMultiDisplayDlg)
{
	m_pMultiDisplayDlg = pMultiDisplayDlg;

	//SetActiveLayout(m_Layoutlist.begin());
	TVLAYOUT_ITER Iter = m_Layoutlist.begin();
	m_ActiveLayoutIter = Iter;

	return TRUE;
}

TVLAYOUT_ITER CTvLayoutManager::AddLayout(TVWALL_LAYOUT_PROPERTY& LayoutProp)
{
	//if(!theDBManager->AddTvWallLayout(LayoutProp, theUser->GetUserID()))
	//{
	//	return m_Layoutlist.end();
	//}

	//TVWALL_LAYOUT_INFO LayoutInfo(LayoutProp);
	CTvWallLayout* pLayout = new CTvWallLayout(static_cast<int>(m_Layoutlist.size()), m_pMultiDisplayDlg, LayoutProp);

	m_Layoutlist.push_back(pLayout);

	TVLAYOUT_ITER Iter = (--(m_Layoutlist.end()));

	return Iter;
}

TVLAYOUT_ITER CTvLayoutManager::AddLayout(LPCTSTR lpszLayoutName)
{
	TVWALL_LAYOUT_PROPERTY Prop;

	Prop.strLayoutName = lpszLayoutName;
	Prop.nStayTime = LAYOUT_TOUR_STAY_TIME_DEFAULT;

	return AddLayout(Prop);
}

BOOL CTvLayoutManager::DeleteLayout(int nIndex)
{
	TVLAYOUT_ITER Iter = GetLayoutIterator(nIndex);
	ASSERT(Iter != EndOfLayoutList());

	CTvWallLayout* pLayout = *Iter;

	//if(!theDBManager->DeleteTvWallLayout(pLayout->GetLayoutID()))
	//{
	//	return FALSE;
	//}

	if(Iter == m_ActiveLayoutIter)
		m_ActiveLayoutIter = EndOfLayoutList();

	m_Layoutlist.erase(Iter++);
	delete pLayout;

	UpdateLayoutIndex(Iter, nIndex);

	return TRUE;
}

void CTvLayoutManager::SetActiveLayout(TVLAYOUT_ITER Iter)
{
	if(Iter == m_ActiveLayoutIter || Iter == EndOfLayoutList())
		return;

	if(m_ActiveLayoutIter != EndOfLayoutList())
	{
		//(*m_ActiveLayoutIter)->TakeSnapshot();
	}

	int nCloseWnd[100] = {0};
	int nMaxWnd = m_pMultiDisplayDlg->GetMaxDisplayNum();

	for(int i = 0; i < nMaxWnd; i++)
	{
		CMediaPlayer* pMediaPlayer = m_pMultiDisplayDlg->GetMediaPlayer(i);
		if(pMediaPlayer /*&& pMediaPlayer->IsPlaying()*/)
		{
			nCloseWnd[i] = 1;
			if (pMediaPlayer->IsLocalRecording())
			{
				m_pMultiDisplayDlg->RecordStop(i);
			}
		}
	}

	CTvWallLayout* pLayout = *Iter;

	const CWndChannelIDMap& WndChannelIDMap = pLayout->GetWndChannelIDMap();
	CWndChannelIDMap::const_iterator it = WndChannelIDMap.begin();

	DWORD dwDisplayStyle = m_pMultiDisplayDlg->GetDisplayStyle();
	if(dwDisplayStyle != DISPLAY_NORMAL && dwDisplayStyle != DISPLAY_MULTI_WND_FULL_SCREEN)
		m_pMultiDisplayDlg->RestoreNormalDisplayStyle();

	//m_pMultiDisplayDlg->SetDisplayNum(pLayout->GetDisplayNumber(), FALSE);

	for(; it != WndChannelIDMap.end(); ++it)
	{
		CChannel* pChannel = thePlatform.FindChannel(it->second);
		if(pChannel)
		{
			m_pMultiDisplayDlg->OpenLive(it->first, pChannel);
			nCloseWnd[it->first] = 0;
		}
	}

	for(int i = 0; i < nMaxWnd; i++)
	{
		if(nCloseWnd[i])
		{
			m_pMultiDisplayDlg->LayoutClear(i);
			//CMediaPlayer* pMediaPlayer = m_pMultiDisplayDlg->GetMediaPlayer(i);
			//pMediaPlayer->Clear();
		}
	}

	m_ActiveLayoutIter = Iter;

	CTvWallLayoutMessage Message(TVWALL_ACTIVE_LAYOUT_CHANGED);

	Message.nLayoutIndex = pLayout->GetIndex();
	Message.Send();
}

CTvWallLayout* CTvLayoutManager::GetNextLayout(TVLAYOUT_ITER& Iter)
{
	CTvWallLayout* pLayout = NULL;

	if(Iter != m_Layoutlist.end())
	{
		pLayout = *Iter;
		++Iter;
	}

	return pLayout;
}

TVLAYOUT_ITER CTvLayoutManager::GetLayoutIterator(int nIndex)
{
	if(nIndex < 0)
		return m_Layoutlist.end();

	TVLAYOUT_ITER Iter = m_Layoutlist.begin();
	for(int i = 0; i < nIndex && Iter != m_Layoutlist.end(); i++)
	{
		++Iter;		
	}

	return Iter;
}

void CTvLayoutManager::SetActiveLayout(int nIndex)
{
	TVLAYOUT_ITER Iter = GetLayoutIterator(nIndex);

	SetActiveLayout(Iter);
}

void CTvLayoutManager::UpdateLayoutIndex(TVLAYOUT_ITER FirstIter, int nFirstIndex)
{
	TVLAYOUT_ITER Iter = FirstIter;
	int nIndex = nFirstIndex;

	for(; Iter != EndOfLayoutList(); ++Iter)
	{
		CTvWallLayout* pLayout = *Iter;
		pLayout->SetIndex(nIndex);
		nIndex++;
	}
}

BOOL CTvLayoutManager::SaveAllLayouts()
{
	if(m_ActiveLayoutIter != m_Layoutlist.end())
	{
		(*m_ActiveLayoutIter)->TakeSnapshot();
	}

	TVLAYOUT_ITER Iter = m_Layoutlist.begin();
	for(; Iter != m_Layoutlist.end(); ++Iter)
	{
		if(!(*Iter)->SaveLayoutInfo())
			break;
	}

	return (Iter == m_Layoutlist.end());
}

BOOL CTvLayoutManager::StartTourLayout()
{
	if(m_bTouring)
		return TRUE;

	if(!m_TourTimer.StartTimer(theAppData.GetLayoutTourTime() * 1000))
	{
		//theErrorLog.SetLastError(_T("start timer failed\n"));
		return FALSE;
	}

	DWORD dwDisplayStyle = m_pMultiDisplayDlg->GetDisplayStyle();
	if(dwDisplayStyle != DISPLAY_NORMAL && dwDisplayStyle != DISPLAY_MULTI_WND_FULL_SCREEN)
		m_pMultiDisplayDlg->RestoreNormalDisplayStyle();

	m_bTouring = TRUE;

	CTvWallLayoutMessage Message(TVWALL_LAYOUT_TOUR_STARTED);
	Message.Send();

	return TRUE;
}

void CTvLayoutManager::StopTourLayout()
{
	if(m_bTouring)
	{
		m_TourTimer.CloseTimer();
		m_bTouring = FALSE;

		CTvWallLayoutMessage Message(TVWALL_LAYOUT_TOUR_STOPPED);
		Message.Send();
	}
}

void CTvLayoutManager::LayoutTourTimerProc(UINT uTimerID, LPVOID pUserData)
{
	CTvLayoutManager* pThis = static_cast<CTvLayoutManager*>(pUserData);

	pThis->m_TourTimer.CloseTimer();

	TVLAYOUT_ITER Iter = pThis->m_ActiveLayoutIter;
	++Iter;

	if(Iter == pThis->m_Layoutlist.end())
		Iter = pThis->m_Layoutlist.begin();

	pThis->SetActiveLayout(Iter);

	pThis->m_TourTimer.StartTimer(theAppData.GetLayoutTourTime() * 1000);
}

void CTvLayoutManager::LoadChannelInfos(int nIndex)
{
	m_bEnableSelChange = TRUE;
	TVLAYOUT_ITER Iter = GetLayoutIterator(nIndex);

	int nCloseWnd[100] = {0};
	int nMaxWnd = m_pMultiDisplayDlg->GetMaxDisplayNum();

	for(int i = 0; i < nMaxWnd; i++)
	{
		CMediaPlayer* pMediaPlayer = m_pMultiDisplayDlg->GetMediaPlayer(i);
		if(pMediaPlayer /*&& pMediaPlayer->IsPlaying()*/)
		{
			nCloseWnd[i] = 1;
		}
	}

	CTvWallLayout* pLayout = *Iter;

	const CWndChannelIDMap& WndChannelIDMap = pLayout->GetWndChannelIDMap();
	CWndChannelIDMap::const_iterator it = WndChannelIDMap.begin();

	for(; it != WndChannelIDMap.end(); ++it)
	{
		CChannel* pChannel = thePlatform.FindChannel(it->second);
		if(pChannel)
		{
			m_pMultiDisplayDlg->OpenLive(it->first, pChannel);
			nCloseWnd[it->first] = 0;
		}
	}

	for(int i = 0; i < nMaxWnd; i++)
	{
		if(nCloseWnd[i])
		{
			m_pMultiDisplayDlg->LayoutClear(i);
		}
	}

	m_ActiveLayoutIter = Iter;
}
